package contextx

import (
	"context"
	"github.com/go-kratos/kratos/v2/transport"
	"github.com/google/uuid"
	"strconv"
)

const (
	HeaderTokenKey       = "TOKEN"   // token 名称
	HeaderClientTypeKey  = "CLIENT"  // 客户端类型
	HeaderClientVerIdKey = "VERSION" // 版本ID
	HeaderSourceKey      = "SOURCE"  // 注册来源名称
	HeaderTimeKey        = "TIME"    // 名称
	HeaderTraceId        = "TRACEID" //
	HeaderUserId         = "UID"     //

)

type Header struct {
	Token   string
	Client  string // 终端 安卓端(android) IOS(ios)Pad端（pad）ipad端(ipad) 小程序端(program) H5网页端(web)
	Version string // v1.0.0
	Source  int32  // 业务来源 1官网 2第三方 3 web 4小程序
	Time    int32  // 123455
	TraceId string
	Uid     string
}

type _header struct {
	ctx       context.Context
	ctxHeader transport.Header
	Header    *Header
}

func NewHeader(ctx context.Context) *_header {

	header := _header{
		ctx:    ctx,
		Header: &Header{}, // 申请内存
	}

	// 解析transport
	if tr, ok := transport.FromServerContext(ctx); ok {
		header.ctxHeader = tr.RequestHeader()
	}

	return &header
}

func (h *_header) GetAll() *Header {

	_ = h.GetToken()
	_ = h.GetClientType()
	_ = h.GetClientVerName()
	_ = h.GetSource()
	_ = h.GetTime()
	_ = h.GetUID()

	return h.Header
}

// GetToken 获取token
func (h *_header) GetUID() (uid string) {
	h.Header.Uid = h.ctxHeader.Get(HeaderUserId)
	return h.Header.Uid
}

// GetToken 获取token
func (h *_header) GetToken() (token string) {

	h.Header.Token = h.ctxHeader.Get(HeaderTokenKey)
	return h.Header.Token
}

// GetClientType
// 终端 android(安卓端) ios(IOS) pad(Pad端) ipad(ipad端 program(小程序端) web(H5网页端)
func (h *_header) GetClientType() (client string) {

	h.Header.Client = h.ctxHeader.Get(HeaderClientTypeKey)

	return h.Header.Client
}

// GetClientVerName 版本名称 v1.8.0
func (h *_header) GetClientVerName() (verName string) {

	h.Header.Version = h.ctxHeader.Get(HeaderClientVerIdKey)

	return h.Header.Version
}

// GetSource 获取业务来源
func (h *_header) GetSource() (sourceId int32) {

	num, err := strconv.ParseInt(h.ctxHeader.Get(HeaderSourceKey), 10, 32)
	if err != nil {
		return
	}
	h.Header.Source = int32(num)

	return h.Header.Source
}

// GetTime 获取时间戳
func (h *_header) GetTime() (time int32) {

	num, err := strconv.ParseInt(h.ctxHeader.Get(HeaderTimeKey), 10, 32)
	if err != nil {
		return
	}
	h.Header.Time = int32(num)

	return h.Header.Time
}

// GetTraceId 获取traceId
func (h *_header) GetTraceId() (traceId string) {

	h.Header.TraceId = h.ctxHeader.Get(HeaderTraceId)

	if h.Header.TraceId == "" {
		h.Header.TraceId = uuid.NewString()
	}
	return h.Header.TraceId
}
